package com.linkhub.oms.dao.mpservice.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.extension.mapping.config.DeepConfig;
import com.github.yulichang.extension.mapping.relation.Relation;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.collect.Lists;
import com.linkhub.oms.common.enums.mp.OrderProductTypeEnum;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.dao.mapper.OrderProductEntityMapper;
import com.linkhub.oms.dao.mpservice.IOrderProductService;
import com.linkhub.oms.dao.mpservice.IShopProductSkuMappingService;
import com.linkhub.oms.entity.LocalProductEntity;
import com.linkhub.oms.entity.OrderProductEntity;
import com.linkhub.oms.entity.ShopProductSkuMappingEntity;
import com.linkhub.oms.entity.resulttype.OrderLocalProductResultEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 订单商品信息表 服务实现类
 * </p>
 *
 * @author echo
 * @since 2024-03-28
 */
@Service
public class OrderProductServiceImpl extends ServiceImpl<OrderProductEntityMapper, OrderProductEntity> implements IOrderProductService {

    @Resource
    private IShopProductSkuMappingService shopProductSkuMappingService;
    @Resource
    private OrderProductEntityMapper orderProductEntityMapper;

    @Override
    public List<Long> listMatchShopSkuIds( String sysShopId, Collection<Long> shopSkuIds ) {

        List<ShopProductSkuMappingEntity> mappings = shopProductSkuMappingService.listSkuMappings(sysShopId, shopSkuIds);
        return QtStreamUtil.map(mappings, ShopProductSkuMappingEntity::getShopSkuId);
    }

    @Override
    public List<String> listLocalOrderLineItemOrderIds( Collection<String> sysOrderIds ) {
        if (CollUtil.isEmpty(sysOrderIds)) {
            return Lists.newArrayListWithCapacity(0);
        }
        return QtStreamUtil.mapAndDistinct(lambdaQuery()
                        .select(OrderProductEntity::getSysOrderId)
                        .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                        .eq(OrderProductEntity::getProductType, OrderProductTypeEnum.LOCAL)
                        .list(),
                OrderProductEntity::getSysOrderId);
    }

    @Override
    public void deleteBySysOrderIds( Collection<String> sysOrderIds, OrderProductTypeEnum productType ) {
        if (CollUtil.isEmpty(sysOrderIds)) {
            return;
        }

        lambdaUpdate()
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .eq(Objects.nonNull(productType), OrderProductEntity::getProductType, productType)
                .remove();
    }

    @Override
    public void deleteBySysOrderIds( Collection<String> sysOrderIds ) {
        this.deleteBySysOrderIds(sysOrderIds, null);
    }

    @Override
    public List<String> listUnMatchSysOrderIds( Collection<String> sysOrderIds ) {
        MPJLambdaWrapper<OrderProductEntity> lambdaWrapper = JoinWrappers.lambda(OrderProductEntity.class);
        lambdaWrapper.distinct()
                .select(OrderProductEntity::getSysOrderId)
                .leftJoin(ShopProductSkuMappingEntity.class, on ->
                        on.eq(OrderProductEntity::getSysShopId, ShopProductSkuMappingEntity::getSysShopId)
                                .eq(OrderProductEntity::getShopSkuId, ShopProductSkuMappingEntity::getShopSkuId))
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .isNull(ShopProductSkuMappingEntity::getId);

        return orderProductEntityMapper.selectJoinList(String.class, lambdaWrapper);
    }

    @Override
    public List<OrderProductEntity> listBySysOrderIds( Collection<String> sysOrderIds, OrderProductTypeEnum productType ) {
        if (CollUtil.isEmpty(sysOrderIds)) {
            return Lists.newArrayListWithCapacity(0);
        }
        return super.lambdaQuery()
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .eq(Objects.nonNull(productType), OrderProductEntity::getProductType, productType)
                .list();
    }

    @Override
    public List<OrderProductEntity> listBySysOrderIds( Collection<String> sysOrderIds ) {
        if (CollUtil.isEmpty(sysOrderIds)) {
            return Lists.newArrayListWithCapacity(0);
        }
        return super.lambdaQuery()
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .list();
    }

    @Override
    public List<OrderProductEntity> listBySysOrderId( String sysOrderId ) {
        if (StringUtils.isBlank(sysOrderId)) {
            return Lists.newArrayListWithCapacity(0);
        }
        return super.lambdaQuery()
                .eq(OrderProductEntity::getSysOrderId, sysOrderId)
                .list();
    }

    @Override
    public List<OrderLocalProductResultEntity> listOrderLocalProducts( Collection<String> sysOrderIds ) {
        MPJLambdaWrapper<OrderProductEntity> lambdaWrapper = JoinWrappers.lambda(OrderProductEntity.class);
        lambdaWrapper
                .select(OrderProductEntity::getSysOrderId,
                        OrderProductEntity::getSysShopId,
                        OrderProductEntity::getShopProductId,
                        OrderProductEntity::getShopSkuId,
                        OrderProductEntity::getCurrencyCode,
                        OrderProductEntity::getCurrentQuantity,
                        OrderProductEntity::getPrice)
                .select(LocalProductEntity::getSku,
                        LocalProductEntity::getSkuId)

                .innerJoin(ShopProductSkuMappingEntity.class, on ->
                        on.eq(OrderProductEntity::getSysShopId, ShopProductSkuMappingEntity::getSysShopId)
                                .eq(OrderProductEntity::getShopSkuId, ShopProductSkuMappingEntity::getShopSkuId))
                .innerJoin(LocalProductEntity.class, on ->
                        on.eq(ShopProductSkuMappingEntity::getSkuId, LocalProductEntity::getSkuId))
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .eq(OrderProductEntity::getProductType, OrderProductTypeEnum.THIRD_PARTY);

        return orderProductEntityMapper.selectJoinList(OrderLocalProductResultEntity.class, lambdaWrapper);
    }

    @Override
    public boolean existOrderLocalProduct( String sysOrderId ) {
        return super.lambdaQuery()
                .eq(OrderProductEntity::getSysOrderId, sysOrderId)
                .eq(OrderProductEntity::getProductType, OrderProductTypeEnum.LOCAL)
                .exists();
    }

    @Override
    public void updateOrderProduct( String orderId, String localSkuId, String shopProductId, OrderProductEntity orderProduct ) {
        super.lambdaUpdate()
                .eq(OrderProductEntity::getSysOrderId, orderId)
                .eq(OrderProductEntity::getSkuId, localSkuId)
                .eq(StringUtils.isNotBlank(shopProductId), OrderProductEntity::getShopProductId, shopProductId)
                .update(orderProduct);
    }

    @Override
    public long countOrderLocalProduct( String sysOrderId ) {
        return super.lambdaQuery()
                .eq(OrderProductEntity::getSysOrderId, sysOrderId)
                .eq(OrderProductEntity::getProductType, OrderProductTypeEnum.LOCAL)
                .count();
    }

    @Override
    public void deleteOrderLocalProduct( String orderId, String skuId, String shopProductId ) {
        super.lambdaUpdate()
                .eq(OrderProductEntity::getSysOrderId, orderId)
                .eq(OrderProductEntity::getSkuId, skuId)
                .eq(StringUtils.isNotBlank(shopProductId), OrderProductEntity::getShopProductId, shopProductId)
                .remove();
    }

    @Override
    public List<OrderProductEntity> listLocalSkuIds( Collection<String> sysOrderIds ) {
        if (CollUtil.isEmpty(sysOrderIds)) {
            return Lists.newArrayListWithCapacity(0);
        }
        return super.lambdaQuery()
                .select(OrderProductEntity::getSysOrderId, OrderProductEntity::getSkuId, OrderProductEntity::getCurrentQuantity)
                .in(OrderProductEntity::getSysOrderId, sysOrderIds)
                .eq(OrderProductEntity::getProductType, OrderProductTypeEnum.LOCAL)
                .list();

    }

    @Override
    public List<OrderProductEntity> deepMappingOrderProduct( List<OrderProductEntity> orderProductEntities ) {

        if (CollUtil.isEmpty(orderProductEntities)) {
            return orderProductEntities;
        }
        return Relation.mpjGetRelation(orderProductEntities, DeepConfig.defaultConfig());
    }
}
